/*
 * ModelCC, distributed under ModelCC Shared Software License, www.modelcc.org
 */

package org.modelcc.io.java;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.logging.Level;

import org.modelcc.metamodel.ModelElement;

/**
 * Java model visitor
 * 
 * @author Fernando Berzal (berzal@acm.org)
 */
public abstract class JavaModelVisitor<E extends ModelElement, F extends ModelElement> 
{
	private JavaModelReader reader;

	public JavaModelVisitor (JavaModelReader reader)
	{
		this.reader = reader;
	}
	
    public void log(Level level, String string, Object[] object) 
    {
        reader.log(level,string,object);
    }
    
    // Methods to be overriden
    
	public void startVisit (Class type, E element) throws Exception
	{
	}
	
	public void endVisit (Class type, E element) throws Exception
	{
	}
	
	public void visit (Class type, Field field, E element) throws Exception
	{
	}

	public void visit (Class type, Method method, E element) throws Exception
	{
	}
	
	public void visit (Field field, F model)
	{
	}

	// Standard visit: startVisit + visit methods + endVisit
	
	public final void visit (Class type, E element)
		throws Exception
	{
    	startVisit(type,element);
    	   	
    	endVisit(type,element);
	}

	public final void visitFields (Class type, E element)
		throws Exception
	{
		Field[] fields = type.getDeclaredFields();

		startVisit(type,element);

		for (Field f: fields) {
			visit(type, f, element);
		}

		endVisit(type, element);
	}

	public final void visitMethods (Class type, E element)
		throws Exception
	{
		Method[] methods = type.getDeclaredMethods();

		startVisit(type, element);

		for (Method m: methods) {
			visit(type, m, element);
		}

		endVisit(type, element);
	}
	
}
